package org.oss.client;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.oss.client.dto.BaseResponse;
import org.oss.client.dto.OssSecurityRequest;
import org.oss.client.dto.UploadRequest;
import org.oss.exception.NestedException;
import org.oss.util.HttpClientUtil;
import org.oss.util.JsonMapper;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.common.comm.IdleConnectionReaper;
import com.oss.base.BaseConst;

public class DefaultClient {
	private static final String SHTML = ".shtml";
	protected JsonMapper mapper = JsonMapper.buildNonEmptyMapper();
	protected String schema;
	protected String host;
	protected int port;
	private String contextPath;
	private CloseableHttpClient httpClient;
	private HttpClientConnectionManager connectionManager;
	
	protected DefaultClient(String schema, String host, int port,String contextPath) {
	    this.schema = schema;
	    this.host = host;
	    this.port = port;
	    this.contextPath=contextPath;
//	    httpClient=HttpClients.createDefault();
	    this.connectionManager = HttpClientUtil.getDefaultConnectionManager();
	    this.httpClient=HttpClientUtil.getHttpClient(connectionManager);
	  }
	
	protected DefaultClient(String host, int port) {
	    this.schema = "http";
	    this.host = host;
	    this.port = port;
	    this.contextPath="oss-web";
	    this.connectionManager = HttpClientUtil.getDefaultConnectionManager();
	    this.httpClient=HttpClientUtil.getHttpClient(connectionManager);
	  }
	
	
	protected DefaultClient(String schema, String host, int port,String contextPath,ClientConfiguration clientConfig) {
	    this.schema = schema;
	    this.host = host;
	    this.port = port;
	    this.contextPath=contextPath;
	    this.connectionManager = HttpClientUtil.getDefaultConnectionManager();
	    this.httpClient=HttpClientUtil.getHttpClient(connectionManager);
	  }
	
	
	

	protected URI createURI(String path) {
		try {
			URI uri = new URIBuilder()
		    .setScheme(this.schema)
		    .setHost(this.host)
		    .setPort(this.port)
		    .setPath(this.contextPath + "/"+path+SHTML)
		    .build();
			return uri;
		    } catch (URISyntaxException e) {
		      throw NestedException.wrap(e);
		    }
	}
	
	protected HttpPost CreatePost(URI uri, String json) {
		HttpPost post = new HttpPost(uri);
		post.setHeader("Connection", "close");
		List<NameValuePair> nvps = new ArrayList <NameValuePair>();  
		nvps.add(new BasicNameValuePair("req", json));
		try {
			post.setEntity(new  UrlEncodedFormEntity(nvps,"utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return post;
	}
	
	protected <T> T  excuteAndParse(CloseableHttpClient client,HttpPost post,Class<T> clazz){
		CloseableHttpResponse response = null;
	    try {
	    	response = client.execute(post);
	    	return this.mapper.fromJson(EntityUtils.toString(response.getEntity(), "UTF-8"),clazz);
	    } catch (Exception e) {
	    	post.abort();
	    	e.printStackTrace();
	    	return null;
	    }
		
	}
	
	

	public CloseableHttpClient getHttpClient() {
		return httpClient;
	}
	
	public void shutdown(){
		try {
			IdleConnectionReaper.removeConnectionManager(connectionManager);
			this.getHttpClient().close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	public  BaseResponse createErrRes(Exception e) {
		BaseResponse res =new BaseResponse();
		res.setResultCode(BaseConst.RESPONSE_CODE_FAILED);
		res.setResultMsg(e.getMessage());
		return res;
	}
	
	protected OssSecurityRequest buildSecurityRquesr(UploadRequest req,String method) {
		OssSecurityRequest securityReq = new OssSecurityRequest();
		securityReq.setPwd(req.getPwd());
		securityReq.setUser(req.getUser());
		securityReq.setMethod(method);
		securityReq.setFileName(req.getFileName());
		securityReq.setFileSize(req.getFile().length());
		return securityReq;
	}

}
